﻿using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Enyim.Caching.Memcached;
using Couchbase;
using Couchbase.Configuration;
using Es;

public class DbCouchbase : IDbCouchbase
{
    //---------------------------------------------------------------------
    CouchbaseClient mCouchbaseClient;
    string mErrorString = "";
    List<object[]> mListView = new List<object[]>();

    //---------------------------------------------------------------------
    public DbCouchbase()
    {
    }

    //---------------------------------------------------------------------
    public bool setup(ref _tCouchbaseInfo couchbase_info)
    {
        try
        {
            CouchbaseClientConfiguration cfg = new CouchbaseClientConfiguration();
            cfg.HttpRequestTimeout = new TimeSpan(0, 0, 30);
            cfg.HeartbeatMonitor.Enabled = true;
            cfg.SocketPool.ConnectionTimeout = new TimeSpan(0, 0, 30);
            cfg.Bucket = couchbase_info.bucket_name;
            cfg.BucketPassword = couchbase_info.bucket_pwd;
            cfg.Username = couchbase_info.user;
            cfg.Password = couchbase_info.pwd;
            cfg.Urls.Add(new Uri(couchbase_info.url));
            mCouchbaseClient = new CouchbaseClient(cfg);

            return true;
        }
        catch (System.Exception ex)
        {
            mErrorString = ex.ToString();
            return false;
        }
    }

    //---------------------------------------------------------------------
    public string getErrorString()
    {
        return mErrorString;
    }

    //---------------------------------------------------------------------
    public bool executeGet(string db_key, out string json_data)
    {
        Enyim.Caching.Memcached.Results.IGetOperationResult<string> ret = mCouchbaseClient.ExecuteGet<string>(db_key);
        if (ret.Success)
        {
            json_data = ret.Value;
            _clearErrorString();
            return true;
        }
        else
        {
            json_data = null;
            return false;
        }
    }

    //---------------------------------------------------------------------
    public bool executeStore(string db_key, string json_data)
    {
        Enyim.Caching.Memcached.Results.IStoreOperationResult ret =
            mCouchbaseClient.ExecuteStore(StoreMode.Set, db_key, json_data, Couchbase.Operations.PersistTo.Zero);
        if (ret.Success)
        {
            _clearErrorString();
            return true;
        }
        else
        {
            mErrorString = db_key + " " + ret.Message;
            return false;
        }
    }

    //---------------------------------------------------------------------
    public bool executeRemove(string db_key)
    {
        Enyim.Caching.Memcached.Results.IRemoveOperationResult ret =
            mCouchbaseClient.ExecuteRemove(db_key);
        if (ret.Success)
        {
            _clearErrorString();
            return true;
        }
        else
        {
            mErrorString = db_key + " " + ret.Message;
            return false;
        }
    }

    //---------------------------------------------------------------------
    public List<object[]> getView(string design_name, string view_name, bool descending = false, int limit = 0)
    {
        IView<IViewRow> v = null;
        if (limit > 0)
        {
            v = mCouchbaseClient.GetView(design_name, view_name).Descending(descending).Limit(limit);
        }
        else
        {
            v = mCouchbaseClient.GetView(design_name, view_name).Descending(descending);
        }

        mListView.Clear();
        foreach (var row in v)
        {
            object[] record = new object[] { row.Info["key"], row.Info["value"] };
            mListView.Add(record);
        }
        return mListView;
    }

    //---------------------------------------------------------------------
    public List<object[]> getView<KeyType>(string design_name, string view_name, KeyType start_key,
                KeyType end_key, bool descending = false, int limit = 0)
    {
        IView<IViewRow> v = null;
        if (limit > 0)
        {
            v = mCouchbaseClient.GetView(design_name, view_name)
                .StartKey<KeyType>(start_key)
                .EndKey<KeyType>(end_key)
                .Descending(descending)
                .Limit(limit);
        }
        else
        {
            v = mCouchbaseClient.GetView(design_name, view_name)
                .StartKey<KeyType>(start_key)
                .EndKey<KeyType>(end_key)
                .Descending(descending);
        }

        mListView.Clear();
        foreach (var row in v)
        {
            object[] record = new object[] { row.Info["key"], row.Info["value"] };
            mListView.Add(record);
        }
        return mListView;
    }

    //---------------------------------------------------------------------
    void _clearErrorString()
    {
        if (mErrorString.Length > 0) mErrorString = "";
    }
}
